package org.android.bbdroid.storage;

import java.util.HashMap;
import java.util.Map;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;

public class ForumsProvider extends ContentProvider
{
  private static final int FORUMS = 0;
  private static final int FORUM_ID = 2;
  private static final int NAMES = 1;
  private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
  private static Map<String, String> projectionMap;
  private ForumsDbHelper helper;

  static
  {
    matcher.addURI(BBDroidUris.AUTHORITY, BBDroidUris.FORUMS, FORUMS);
    matcher.addURI(BBDroidUris.AUTHORITY, BBDroidUris.NAMES, NAMES);
    matcher.addURI(BBDroidUris.AUTHORITY, BBDroidUris.FORUM_ID, FORUM_ID);
    
    projectionMap = new HashMap<String,String>();
    projectionMap.put(BBDroidUris.ForumsColums._ID, BBDroidUris.ForumsColums._ID);
    projectionMap.put(BBDroidUris.ForumsColums.FORUM_NAME, BBDroidUris.ForumsColums.FORUM_NAME);
    projectionMap.put(BBDroidUris.ForumsColums.FORUM_URL, BBDroidUris.ForumsColums.FORUM_URL);
  }

  public int delete(Uri uri, String where, String[] selection)
  {
    SQLiteDatabase db = this.helper.getWritableDatabase();
    int result;
    switch (matcher.match(uri))
    {
    case FORUMS:
      result = db.delete(ForumsDbHelper.TABLE_NAME, where, selection);
      break;
    case FORUM_ID:
    {
    	String finalWhere =BBDroidUris.ForumsColums._ID +" = " + uri.getPathSegments().get(1);
    	finalWhere+= (where==null? "" : where);
    	result=db.delete(ForumsDbHelper.TABLE_NAME, finalWhere, selection);
    	break;
    }
    case NAMES:
    {
    	String finalWhere =BBDroidUris.ForumsColums.FORUM_NAME +" = " + uri.getPathSegments().get(1);
    	finalWhere = finalWhere + where==null? "" : where;
    	result=db.delete(ForumsDbHelper.TABLE_NAME, finalWhere, selection);
    	break;
    }
    default:
        throw new IllegalArgumentException("Unknown URI " + uri);
    }
    
    getContext().getContentResolver().notifyChange(uri, null);
    return result;
  }

  public String getType(Uri uri)
  {
    switch (matcher.match(uri))
    {
    case FORUMS:
    	return BBDroidUris.CONTENT_TYPE;

    case FORUM_ID:
    case NAMES:
    	return BBDroidUris.CONTENT_ITEM_TYPE;

    default:
    	throw new IllegalArgumentException("Unknown URI " + uri);
    }
  }

  public Uri insert(Uri uri, ContentValues initialContentValues)
  {
    if (matcher.match(uri) != FORUMS)
      throw new IllegalArgumentException("Unknown URI " + uri);
    
    ContentValues values;
    if (initialContentValues!=null){
    	values=new ContentValues(initialContentValues);
    }else values=new ContentValues();

    if (!values.containsKey(BBDroidUris.ForumsColums.FORUM_NAME))
    	values.put(BBDroidUris.ForumsColums.FORUM_NAME, Resources.getSystem().getString(android.R.string.untitled));
    if (!values.containsKey(BBDroidUris.ForumsColums.FORUM_URL))
      values.put(BBDroidUris.ForumsColums.FORUM_URL, "");
      
    long result=helper.getWritableDatabase().insert(ForumsDbHelper.TABLE_NAME, BBDroidUris.ForumsColums.FORUM_NAME, values);
    if(result<=0)
    	 throw new SQLException("Failed to insert row into " + uri);
    
    Uri localUri = ContentUris.withAppendedId(BBDroidUris.ForumsColums.CONTENT_URI, result);
    getContext().getContentResolver().notifyChange(localUri, null);
    return localUri;
  }

  public boolean onCreate()
  {
    this.helper = new ForumsDbHelper(getContext());
    return true;
  }

  public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
  {
      SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
      qb.setTables(ForumsDbHelper.TABLE_NAME);
      
      switch (matcher.match(uri)) {
          case FORUMS:
              qb.setProjectionMap(projectionMap);
              break;

          case FORUM_ID:
              qb.setProjectionMap(projectionMap);
              qb.appendWhere(
                  BBDroidUris.ForumsColums._ID +
                  "=" +
                  uri.getPathSegments().get(1));
              break;

          case NAMES:
              qb.setProjectionMap(projectionMap);
              qb.appendWhere(
                  BBDroidUris.ForumsColums.FORUM_NAME +
                  "=" +
                  uri.getPathSegments().get(1));
              break;

          default:
              throw new IllegalArgumentException("Unknown URI " + uri);
      }


      String orderBy;
      // If no sort order is specified, uses the default
      if (TextUtils.isEmpty(sortOrder)) {
          orderBy = BBDroidUris.ForumsColums.DEFAULT_SORT_ORDER;
      } else {
          // otherwise, uses the incoming sort order
          orderBy = sortOrder;
      }

      // Opens the database object in "read" mode, since no writes need to be done.
      SQLiteDatabase db = helper.getReadableDatabase();

      Cursor c = qb.query(
          db,            // The database to query
          projection,    // The columns to return from the query
          selection,     // The columns for the where clause
          selectionArgs, // The values for the where clause
          null,          // don't group the rows
          null,          // don't filter by row groups
          orderBy        // The sort order
      );
      c.setNotificationUri(getContext().getContentResolver(), uri);
      return c;
  }

  public int update(Uri uri, ContentValues values, String where, String[] whereArgs)
  {
      SQLiteDatabase db = helper.getWritableDatabase();
      int count;
      String finalWhere;

      switch (matcher.match(uri)) {

          case FORUMS:

              // Does the update and returns the number of rows updated.
              count = db.update(
                  ForumsDbHelper.TABLE_NAME, // The database table name.
                  values,                   // A map of column names and new values to use.
                  where,                    // The where clause column names.
                  whereArgs                 // The where clause column values to select on.
              );
              break;

          case FORUM_ID:
              
              finalWhere =
                      BBDroidUris.ForumsColums._ID +                              
                      " = " +                                          
                      uri.getPathSegments().get(1);

              if (where !=null) {
                  finalWhere = finalWhere + " AND " + where;
              }

              count = db.update(
                  ForumsDbHelper.TABLE_NAME, // The database table name.
                  values,                   // A map of column names and new values to use.
                  finalWhere,               // The final WHERE clause to use
                                            // placeholders for whereArgs
                  whereArgs                 // The where clause column values to select on, or
                                            // null if the values are in the where argument.
              );
              break;
          case NAMES:
              finalWhere =
                      BBDroidUris.ForumsColums.FORUM_NAME +                             
                      " = " +                                         
                      uri.getPathSegments().get(1);
              if (where !=null) {
                  finalWhere = finalWhere + " AND " + where;
              }

              count = db.update(
                  ForumsDbHelper.TABLE_NAME, // The database table name.
                  values,                   // A map of column names and new values to use.
                  finalWhere,               // The final WHERE clause to use
                                            // placeholders for whereArgs
                  whereArgs                 // The where clause column values to select on, or
                                            // null if the values are in the where argument.
              );
              break;
          default:
              throw new IllegalArgumentException("Unknown URI " + uri);
      }

      getContext().getContentResolver().notifyChange(uri, null);
      return count;
  }

  private static class ForumsDbHelper extends SQLiteOpenHelper
  {
    static final String DB_NAME = "forums.db";
    static final int DB_VERSION = 1;
    static final String TABLE_NAME = "forums";

    public ForumsDbHelper(Context c)
    {
      super(c,DB_NAME, null, DB_VERSION);
    }

    public void onCreate(SQLiteDatabase paramSQLiteDatabase)
    {
      paramSQLiteDatabase.execSQL("CREATE TABLE "+TABLE_NAME+" ("+
    		  					   BBDroidUris.ForumsColums._ID+" INTEGER PRIMARY KEY,"+
    		  					   BBDroidUris.ForumsColums.FORUM_NAME+" TEXT,"+
    		  					   BBDroidUris.ForumsColums.FORUM_URL+" TEXT);");
    }

    public void onUpgrade(SQLiteDatabase paramSQLiteDatabase, int paramInt1, int paramInt2)
    {
    }
  }
}